home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / C / Applications / RandomDot 1.1.0 / source / Main.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-07-07  |  12.0 KB  |  529 lines  |  [TEXT/KAHL]

  1. /* main.c - main file of RandomDot
  2.     by David Phillip Oster October 1994 oster@netcom.com
  3.     for:
  4.     Stuart Inglis singlis@waikato.ac.nz
  5.     Department of Computer Science
  6.     University of Waikato, Hamilton, New Zealand
  7.  */
  8. #include "RandomDotMain.h"
  9. #include "RandomDotRes.h"
  10.  
  11. #include "RandomDotWin.h"
  12. #include "Error.h"
  13. #include "Help.h"
  14. #include "Menu.h"
  15. #include "Utils.h"
  16. #include "ZoomCode.h"
  17. #include <AppleEvents.h>
  18. #include <Folders.h>
  19. #include <GestaltEqu.h>
  20.  
  21.  
  22. #define bDoOpenCommandOnce    (1L << 0)
  23. #define bDoHelpCommandOnce    (1L << 1)
  24. #define bDone                (1L << 2)
  25.  
  26. /* *** globals
  27.  */
  28. StringPtr    emptyS = "\p";
  29. Integer        appResFile = -1;    /* our own resID */
  30. Integer        prefResFile = -1;    /* preferences file resID */
  31. FSSpec        prefSpec;            /* file spec for preferences file */
  32. SysEnvRec    world;
  33. Boolean        all_done = FALSE;
  34.  
  35. /* forward declarations.
  36.  */
  37.  
  38. /* *** local to this file.
  39.  */
  40. static LongInt localEventSelect = 0;
  41. void Initialize();
  42.  
  43.  
  44. /* FSSpecFunc - call this with an FSSpecPtr and return an OSErr
  45.  */
  46. typedef OSErr (*FSSpecFunc)(FSSpecPtr);
  47.  
  48. /* BetaExpired - TRUE is later than August 1, 1994
  49. >>>
  50.  */
  51. static Boolean BetaExpired(void){
  52.     return FALSE;
  53. }
  54.  
  55. /* InitPreferences - Initialize the preferences file and connect to it.
  56.  */
  57. static OSErr InitPreferences(void){
  58.     OSErr    errCode;
  59.  
  60.     if(noErr == (errCode = FindFolder(kOnSystemDisk, kPreferencesFolderType, kDontCreateFolder, &prefSpec.vRefNum, &prefSpec.parID))){
  61.         GetIndString(prefSpec.name, kMainStrs, kPrefNameS);
  62.         if(-1 == (prefResFile = FSpOpenResFile(&prefSpec, fsRdWrPerm))){
  63.             localEventSelect |= bDoHelpCommandOnce;
  64.             FSpCreateResFile(&prefSpec, kCreator, kPrefType, NIL);
  65.             if(noErr == (errCode = ResError())){
  66.                 prefResFile = FSpOpenResFile(&prefSpec, fsRdWrPerm);
  67.             }
  68.         }
  69.     }
  70.     return errCode;
  71. }
  72.  
  73. /* MissedAEParameters - 
  74.  */
  75. static OSErr MissedAEParameters(AppleEvent *message){
  76.     DescType typeCode;
  77.     Size actualSize;
  78.     OSErr err;
  79.  
  80.     if(errAEDescNotFound == (err = AEGetAttributePtr(message, keyMissedKeywordAttr, typeWildCard,
  81.             &typeCode, NIL, 0L, &actualSize))){
  82.  
  83.         return noErr;
  84.     }
  85.     return (noErr == err ? errAEEventNotHandled : err);
  86. }
  87.  
  88. /* FSOpenWD - convenience function for opening a wRef
  89.  */
  90. static OSErr FSOpenWD(Integer vRef, LongInt dirId, OSType signature, Integer *wRef){
  91.     WDPBRec    io;
  92.     OSErr    val;
  93.  
  94.     io.ioNamePtr    = NIL;
  95.     io.ioVRefNum    = vRef;
  96.     io.ioWDDirID    = dirId;
  97.     io.ioWDProcID    = signature;
  98.     if(noErr == (val = PBOpenWD(&io, FALSE))){
  99.         *wRef = io.ioVRefNum;
  100.     }
  101.     return val;
  102. }
  103.  
  104. /* DirIDVRefToWRef - given a dirId, vRef pair, return the working ref
  105.  */
  106. static OSErr DirIDVRefToWRef(Integer vRef, LongInt dirID, Integer *wRefp){
  107.     return FSOpenWD(vRef, dirID, 'ERIK', wRefp);
  108. }
  109.  
  110.  
  111. static OSErr OpenPrint(AppleEvent *message, AppleEvent *reply, LongInt refCon, FSSpecFunc f){
  112.     FSSpec        fss;
  113.     AEDescList    docList;
  114.     LongInt        index, itemsInList;
  115.     Size        actualSize;
  116.     AEKeyword    keywd;
  117.     DescType    typeCode;
  118.     OSErr        err;
  119.  
  120.     if((err = AEGetParamDesc(message, keyDirectObject, typeAEList, &docList)) != noErr ||
  121.         (err = MissedAEParameters(message)) != noErr ||
  122.         (err = AECountItems(&docList, &itemsInList)) != noErr){
  123.         return err;
  124.     }
  125.  
  126.     for(index = 1; index <= itemsInList; index++){
  127.         if(noErr != (err = AEGetNthPtr(&docList, index, typeFSS, &keywd, &typeCode,
  128.                     (Ptr)&fss, sizeof(FSSpec), &actualSize))){
  129.             break;
  130.         }
  131.         if(noErr != (err = (*f)(&fss))){
  132.             break;
  133.         }
  134.     }
  135.     return AEDisposeDesc(&docList);
  136. }
  137.  
  138. /* DoOpenApp - We get this if we weren't given any documents.
  139.     Nothing to do for now in RandomDot
  140.  */
  141. static pascal OSErr DoOpenApp(AppleEvent *message, AppleEvent *reply, LongInt refCon){
  142.     OSErr err;
  143.  
  144.     if ((err = MissedAEParameters(message)) != noErr){
  145.         return err;
  146.     }
  147.     return noErr;
  148. }
  149.  
  150. /* RandomDotOpen1 - wrapper for RandomDotOpen when we don't know the script code.
  151.  */
  152. static OSErr RandomDotOpen1(FSSpecPtr fs){
  153.     return TellError(RandomDotOpen(fs, smSystemScript));
  154. }
  155.  
  156. /* DoOpenDoc
  157.  */
  158. static pascal OSErr DoOpenDoc(AppleEvent *message, AppleEvent *reply, LongInt refCon){
  159.     return OpenPrint(message, reply, refCon, RandomDotOpen1);
  160. }
  161.  
  162. /* DoPrintDoc
  163.  */
  164. static pascal OSErr DoPrintDoc(AppleEvent *message, AppleEvent *reply, LongInt refCon){
  165.     return OpenPrint(message, reply, refCon, RandomDotOpen1);
  166. }
  167.  
  168. /* DoQuitApp - 
  169.  */
  170. static pascal OSErr DoQuitApp(AppleEvent *message, AppleEvent *reply, LongInt refcon){
  171.     OSErr err;
  172.  
  173.     if ((err = MissedAEParameters(message)) != noErr){
  174.         return err;
  175.     }
  176.     localEventSelect |= bDone;
  177.     return noErr;
  178. }
  179.  
  180. static void InitAppleEventHandlers(void){
  181.     LongInt    response;
  182.  
  183.     if(noErr == Gestalt(gestaltAppleEventsAttr, &response) && 
  184.         (response & (1L << gestaltAppleEventsPresent))){
  185.  
  186.         AEInstallEventHandler(kCoreEventClass, kAEOpenApplication, 
  187.                 NewAEEventHandlerProc(DoOpenApp), 0, FALSE);
  188.         AEInstallEventHandler(kCoreEventClass, kAEOpenDocuments,
  189.                 NewAEEventHandlerProc(DoOpenDoc), 0, FALSE);
  190.         AEInstallEventHandler(kCoreEventClass, kAEPrintDocuments,
  191.                 NewAEEventHandlerProc(DoPrintDoc), 0, FALSE);
  192.         AEInstallEventHandler(kCoreEventClass, kAEQuitApplication,
  193.                 NewAEEventHandlerProc(DoQuitApp), 0, FALSE);
  194.     }
  195. }
  196.  
  197. /* InitPopUpMenus - initialize menus used in popup
  198.  */
  199. static void InitPopUpMenus(Integer resId){
  200.     Integer     n;
  201.     Integer        **h;
  202.     SignedByte    state;
  203.  
  204.     if(NIL != (h = (Integer    **) Get1Resource('MBAR', resId))){
  205.         LoadResource((Handle) h);
  206.         state = HGetState((Handle) h);
  207.         HNoPurge((Handle) h);
  208.         HLock((Handle) h);
  209.         n = (*h)[ **h ]; 
  210.         while( NIL != GetMenu(++n) ){
  211.             /* empty */
  212.         }
  213.         HSetState((Handle) h, state);
  214.     }
  215. }
  216.  
  217.  
  218.  
  219. /* Init 
  220.  */
  221. void Initialize()
  222. {
  223.     InitGraf(&qd.thePort);
  224.     InitFonts();
  225.     FlushEvents(everyEvent, 0);
  226.     InitWindows();
  227.     InitMenus();
  228.     TEInit();
  229.     InitDialogs(0L);
  230.     InitCursor();
  231.     SetMenuBar(GetNewMBar(kMBAR));
  232.     DrawMenuBar();
  233.     appResFile = CurResFile();
  234.     InitPopUpMenus(kMBAR);
  235.     AddResMenu(GetMHandle(kAppleMenu), 'DRVR');
  236.     SysEnvirons(1, &world);
  237.     if(NOT (world.hasColorQD && world.systemVersion >= 0x700)){
  238.         TellError(eNeed7AndColor);
  239.         ExitToShell();
  240.     }
  241.     InitHelpItem();
  242.     TellError(InitPreferences());
  243.     TellError(InitRandomDot());
  244.     InitAppleEventHandlers();
  245. }
  246.  
  247. /* GoHighLevelEvent - dispatch to apple event processor
  248.  */
  249. static void GoHighLevelEvent(EventRecord *theEvent){
  250.     AEProcessAppleEvent(theEvent);
  251. }
  252.  
  253.  
  254. /* GoMenuBar - 
  255.  */
  256. static void GoMenuBar(EventRecord *event){
  257.     SetCursor(&qd.arrow);
  258.     GoMenu(MenuSelect(event->where));
  259. }
  260.  
  261. /* GoKey - the keystroke handler
  262.  */
  263. static void GoKey(EventRecord *event){
  264.     WindowPtr    win;
  265.  
  266.     if(cmdKey & event->modifiers){
  267.         GoMenu(MenuKey((char) event->message));
  268.     }else if(NIL != (win = FrontWindow())){
  269.         SetPort(win);
  270.         RandomDotKey(event);
  271.     }
  272. }
  273.  
  274. /* GoAway - handle click in goAway box.
  275.  */
  276. static void GoAway(EventRecord *e, WindowPtr win){
  277.     if(TrackGoAway(win, e->where)){
  278.         DoCloseWin(win);
  279.     }
  280. }
  281.  
  282. /* GoDrag - handle drag event on title bar
  283.  */
  284. static void GoDrag(EventRecord *e, WindowPtr win){
  285.     Rect    limitR;
  286.  
  287.     limitR = (**LMGetGrayRgn()).rgnBBox;
  288.     DragWindow(win, e->where, &limitR);
  289. }
  290.  
  291. static void GoGrow(EventRecord *e, WindowPtr win){
  292.     Rect        r;
  293.     LongInt        amount;
  294.     WindowPtr    savePort;
  295.  
  296.     GetPort(&savePort);
  297.     SetPort(win);
  298.     RandomDotGrowBounds(&r);
  299.     if(0 != (amount = GrowWindow(win, e->where, &r))){
  300.         SizeWindow(win, LoWord(amount), HiWord(amount), FALSE);
  301.         InvalRect(&win->portRect);
  302.         RandomDotGrow();
  303.     }
  304.     SetPort(savePort);
  305. }
  306.  
  307. static void GoContent(EventRecord *e, WindowPtr win){
  308.     SetPort(win);
  309.     RandomDotClick(e);
  310. }
  311.  
  312. /* GoZoom - user clicked in zoom area.
  313.  */
  314. static void GoZoom(EventRecord *e, WindowPtr win, Integer sel){
  315.     WindowPtr    savePort;
  316.  
  317.     GetPort(&savePort);
  318.     SetPort(win);
  319.     if(TrackBox(win, e->where, sel)){
  320.         SetPort(win);
  321.         ZoomTheWindow((WindowPeek) win, sel, RandomDotIdealSize);
  322.         InvalRect(&win->portRect);
  323.         RandomDotGrow();
  324.     }
  325.     SetPort(savePort);
  326. }
  327.  
  328.  
  329. /* GoMouseDown - the mouse down tracker
  330.  */
  331. static void GoMouseDown(EventRecord *event, Boolean allOK){
  332.     Integer        sel;
  333.     WindowPtr    win;
  334.  
  335.     sel = FindWindow(event->where, &win);
  336.     switch(sel){
  337.     case inMenuBar:        if(allOK){ GoMenuBar(event); }            break;
  338.     case inGoAway:        if(allOK){ GoAway(event, win); }        break;
  339.     case inDrag:        GoDrag(event, win);                        break;
  340.     case inGrow:        if(allOK){ GoGrow(event, win); }        break;
  341.     case inContent:        if(allOK){ GoContent(event, win); }        break;
  342.     case inZoomIn:
  343.     case inZoomOut:        if(allOK){ GoZoom(event, win, sel); }    break;
  344.     case inSysWindow:    SystemClick(event, win);                break;
  345.     }
  346. }
  347.  
  348. /* GoIdle - 
  349.  */
  350. static void GoIdle(EventRecord *e){
  351.     WindowPtr    win;
  352.  
  353.     if(NIL != (win = FrontWindow()) && userKind == ((WindowPeek) win)->windowKind){
  354.         SetPort(win);
  355.         RandomDotIdle(e);
  356.     }
  357. }
  358.  
  359. /* ModelessFilterProc - wrapper around StdFilterProc to get the window
  360.     correct.
  361.  */
  362. static Boolean ModelessFilterProc(EventRecord *e, DialogPtr *dpp, Integer *itemp){
  363.     DialogPtr    dp;
  364.     static ModalFilterUPP    stdFilerProc = NIL;
  365.  
  366.     switch(e->what){
  367.     case updateEvt:
  368.     case activateEvt:    dp = (DialogPtr) e->message;    break;
  369.     default:            dp = FrontWindow();    break;
  370.     }
  371.     if(NIL == stdFilerProc){
  372.         GetStdFilterProc(&stdFilerProc);
  373.     }
  374.     if(CallModalFilterProc(stdFilerProc, dp, e, itemp)){
  375.         *dpp = dp;
  376.         return TRUE;
  377.     }
  378.     return FALSE;
  379. }
  380.  
  381. /* DeviceLoopUpdate - interface between devicelop and our update procedure.
  382.  */
  383. static pascal void DeviceLoopUpdate(Integer depth, Integer flags, GDHandle gdev, LongInt refCon){
  384.     RandomDotUpdate();
  385. }
  386.  
  387. /* GoUpdate - stack the port, dispatch the update
  388.  */
  389. static void GoUpdate(EventRecord *e){
  390.     WindowPtr    savePort;
  391.     static DeviceLoopDrawingUPP deviceLoopUpdate = NIL;
  392.  
  393.     if(NIL == deviceLoopUpdate){
  394.         deviceLoopUpdate = NewDeviceLoopDrawingProc(DeviceLoopUpdate);
  395.     }
  396.     GetPort(&savePort);
  397.     SetPort((WindowPtr) e->message);
  398.     BeginUpdate((WindowPtr) e->message);
  399.     DeviceLoop(qd.thePort->visRgn, deviceLoopUpdate, 0, 0);
  400.     EndUpdate((WindowPtr) e->message);
  401.     if(NIL != savePort){
  402.         SetPort(savePort);
  403.     }
  404. }
  405.  
  406. /* GoActivateEvent - activate sets the port. deactivate stacks theport.
  407.  */
  408. static void GoActivateEvent(EventRecord *e){
  409.     WindowPtr    savePort;
  410.  
  411.     if(userKind == ((WindowPeek) e->message)->windowKind){
  412.         GetPort(&savePort);
  413.         SetPort((WindowPtr) e->message);
  414.         if(activeFlag & e->modifiers){
  415.             RandomDotActivate();
  416.         }else{
  417.             RandomDotDeactivate();
  418.             if(NIL != savePort){
  419.                 SetPort(savePort);
  420.             }
  421.         }
  422.     }
  423. }
  424.  
  425. /* GoOSEvent - 
  426.  */
  427. static void GoOSEvent(EventRecord *e){
  428.     WindowPtr    win;
  429.  
  430.     switch((e->message >> 12) & 0xFF){
  431.     case suspendResumeMessage:
  432.         if(resumeFlag & e->modifiers){
  433.             if(NIL != (win = FrontWindow()) && userKind == ((WindowPeek) win)->windowKind){
  434.                 SetPort(win);
  435.                 RandomDotActivate();
  436.             }
  437.         }else{
  438.             if(NIL != (win = FrontWindow()) && userKind == ((WindowPeek) win)->windowKind){
  439.                 SetPort(win);
  440.                 RandomDotDeactivate();
  441.             }
  442.         }
  443.         break;
  444.     }
  445. }
  446.  
  447.  
  448.  
  449. /* GoEvent - main event dispatcher.
  450.  */
  451. static void GoEvent(EventRecord *e){
  452.     DialogPtr    dp;
  453.     Integer        item;
  454.  
  455.     if(IsDialogEvent(e) && 
  456.         (ModelessFilterProc(e, &dp, &item) || 
  457.         DialogSelect(e, &dp, &item)) &&
  458.         NIL != dp){
  459. #if 0
  460.             if(gRandomDotConfig == dp){
  461.                 DoRandomDotConfigItem(item);
  462.             }
  463. #endif
  464.             return;
  465.     }
  466.     switch(e->what){
  467.     case nullEvent:            GoIdle(e);            break;
  468.     case mouseDown:            GoMouseDown(e, TRUE);    break;
  469.     case autoKey:            
  470.     case keyDown:            GoKey(e);            break;
  471.     case updateEvt:            GoUpdate(e);        break;
  472.     case activateEvt:        GoActivateEvent(e);    break;
  473.     case osEvt:                GoOSEvent(e);        break;
  474.     case kHighLevelEvent:    GoHighLevelEvent(e);    break;
  475.     default:                break;
  476.     }
  477. }
  478.  
  479. /* DialogOnTopGoEvent - call this when we can't handle keydowns or update events.
  480.     and the only legal mouse events are window drags.
  481.  */
  482. void DialogOnTopGoEvent(EventRecord *e){
  483.     switch(e->what){
  484.     case nullEvent:            GoIdle(e);            break;
  485.     case mouseDown:            GoMouseDown(e, FALSE);        break;
  486.     case activateEvt:        GoActivateEvent(e);    break;
  487.     case osEvt:                GoOSEvent(e);        break;
  488.     case kHighLevelEvent:    GoHighLevelEvent(e);    break;
  489.     default:                break;
  490.     }
  491. }
  492.  
  493.  
  494. /* HandleEvents - 
  495.  */
  496. void HandleEvents(void){
  497.     EventRecord e;
  498.  
  499.     if(0 != localEventSelect){
  500.         if(localEventSelect & bDone){
  501.         all_done = TRUE;
  502.             DoQuit();
  503.         }
  504.         if(localEventSelect & bDoOpenCommandOnce){
  505.             localEventSelect &= ~bDoOpenCommandOnce;
  506.             DoOpen();
  507.         }
  508.         if(localEventSelect & bDoHelpCommandOnce){
  509.             localEventSelect &= ~bDoHelpCommandOnce;
  510.             DoHelp();
  511.         }
  512.     }
  513.     WaitNextEvent(everyEvent, &e, NIL, 0);
  514.     GoEvent(&e);    /* allow null event processing */
  515. }
  516.  
  517.  
  518. /* main
  519.  */
  520. void main()
  521. {
  522.     Initialize();
  523.     while (!all_done)
  524.     {
  525.         HandleEvents();
  526.     }
  527.     ExitToShell();
  528. }
  529.